﻿using System;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Xml.Linq;
using Kevin.Shop.Business.Service.Entity.Helper;
using Kevin.Shop.Business.Service.Entity.SalesManagement.Order;
using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.TenPayLibV3;
using WeixinPay.Business;
using WeixinPay.Models;

namespace WeixinPay.Controllers
{
    /// <summary>
    /// 根据官方的Webforms Demo改写，所以可以看到直接Response.Write()之类的用法，实际项目中不提倡这么做。
    /// </summary>
    public class TenPayV3Controller : Controller
    {
        private static TenPayV3Info _tenPayV3Info;

        public static TenPayV3Info TenPayV3Info
        {
            get
            {
                if (_tenPayV3Info == null)
                {
                    _tenPayV3Info = new TenPayV3Info(ConfigurationManager.AppSettings["TenPayV3_AppId"],
                                                    ConfigurationManager.AppSettings["TenPayV3_AppSecret"],
                                                    ConfigurationManager.AppSettings["TenPayV3_MchId"],
                                                    ConfigurationManager.AppSettings["TenPayV3_Key"], ConfigurationManager.AppSettings["TenPayV3_TenpayNotify"]);//TenPayV3InfoCollection.Data[System.Configuration.ConfigurationManager.AppSettings["TenPayV3_MchId"]];
                }
                return _tenPayV3Info;
            }
        }

        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 获取用户的OpenId
        /// </summary>
        /// <returns></returns>
        public ActionResult GetOpenId()
        {
            ViewData["UrlUserInfo"] = OAuth.GetAuthorizeUrl(TenPayV3Info.AppId, "http://weixin.senparc.com/TenPayV3/JsApi", "JeffreySu", OAuthScope.snsapi_userinfo);

            return View();
        }

        public ActionResult JsApi(string code, string state)
        {
            string orderNumber = Request["orderNumber"];
            if (string.IsNullOrEmpty(code))
            {
                Response.Redirect(OAuth.GetAuthorizeUrl(TenPayV3Info.AppId, "http://m.rongji365.com/WxTrade/TenPayV3/JsApi", orderNumber, OAuthScope.snsapi_base));
                return View();
            }

            //通过，用code换取access_token
            var openIdResult = OAuth.GetAccessToken(TenPayV3Info.AppId, TenPayV3Info.AppSecret, code);
            if (openIdResult.errcode != ReturnCode.请求成功)
            {
                return Content("错误：" + openIdResult.errmsg);
            }

            string timeStamp = "";
            string nonceStr = "";
            string paySign = "";
            orderNumber = state;


            //创建支付应答对象
            RequestHandler packageReqHandler = new RequestHandler(null);
            //初始化
            packageReqHandler.Init();
            //packageReqHandler.SetKey(""/*TenPayV3Info.Key*/);
            var order = ServiceHelper.GetOrderDetailInfo(orderNumber);
            string strTimeFlage = DateTime.Now.Millisecond.ToString();
            string orderNumberFlage = orderNumber.Trim() + "_" + strTimeFlage;
            timeStamp = TenPayUtil.GetTimestamp();
            nonceStr = TenPayUtil.GetNoncestr();
            TenPayV3Info.TenPayV3Notify = ConfigurationManager.AppSettings["TenPayV3_TenpayNotify"];
            //设置package订单参数
            packageReqHandler.SetParameter("appid", TenPayV3Info.AppId);		  //公众账号ID
            packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId);		  //商户号
            packageReqHandler.SetParameter("nonce_str", nonceStr);                    //随机字符串
            packageReqHandler.SetParameter("body", "蓉记鲜鲜鲜-购买商品");
            packageReqHandler.SetParameter("out_trade_no", orderNumberFlage);		//商家订单号
            packageReqHandler.SetParameter("total_fee", (order.OrderPayAmount * 100M).ToString("0"));			        //商品金额,以分为单位(money * 100).ToString()
            packageReqHandler.SetParameter("spbill_create_ip", Request.UserHostAddress);   //用户的公网ip，不是商户服务器IP
            packageReqHandler.SetParameter("notify_url", TenPayV3Info.TenPayV3Notify);		    //接收财付通通知的URL
            packageReqHandler.SetParameter("trade_type", TenPayV3Type.JSAPI.ToString());	                    //交易类型
            packageReqHandler.SetParameter("openid", openIdResult.openid);	                    //用户的openId

            string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
            packageReqHandler.SetParameter("sign", sign);	                    //签名

            string data = packageReqHandler.ParseXML();

            var result = TenPayV3.Unifiedorder(data);
            var res = XDocument.Parse(result);
            string prepayId = res.Element("xml").Element("prepay_id").Value;

            //设置支付参数
            RequestHandler paySignReqHandler = new RequestHandler(null);
            paySignReqHandler.SetParameter("appId", TenPayV3Info.AppId);
            paySignReqHandler.SetParameter("timeStamp", timeStamp);
            paySignReqHandler.SetParameter("nonceStr", nonceStr);
            paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
            paySignReqHandler.SetParameter("signType", "MD5");
            paySign = paySignReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);

            ViewData["appId"] = TenPayV3Info.AppId;
            ViewData["timeStamp"] = timeStamp;
            ViewData["nonceStr"] = nonceStr;
            ViewData["package"] = string.Format("prepay_id={0}", prepayId);
            ViewData["paySign"] = paySign;

            ViewBag.AppId = TenPayV3Info.AppId; ;
            ViewBag.timeStamp = timeStamp;
            ViewBag.NonceStr = nonceStr;
            ViewBag.Package = string.Format("prepay_id={0}", prepayId); ;
            ViewBag.SignType = "MD5";
            ViewBag.Sign = paySignReqHandler.CreateMd5Sign("key", TenPayV3Info.Key); ;

            return View();
        }

        public ActionResult PayNotifyUrl()
        {
            try
            {
                //Url信息
                var sign = Request.Form["sign"];
                var trade_mode = Request.Form["trade_mode"];
                var trade_state = Request.Form["trade_state"];
                var partner = Request.Form["partner"];
                var bank_type = Request.Form["bank_type"];
                var total_fee = Request.Form["total_fee"];
                var fee_type = Request.Form["fee_type"];
                var notify_id = Request.Form["notify_id"];
                var transaction_id = Request.Form["transaction_id"];
                var out_trade_no = Request.Form["out_trade_no"];
                var time_end = Request.Form["time_end"];

                //PostData信息
                var receivedData = new ReceivedData(Request, 1);
                Kevin.Comm.Logger.Tracer.TraceLog(receivedData.RawXml, "weixinPayNotify", "weixinPayNotify", false);
                string orderNumberFlage = receivedData.OrderNumber;
                if (receivedData.OrderNumber.Contains("_") && receivedData.OrderNumber.Split('_').Length == 2)
                {
                    orderNumberFlage = receivedData.OrderNumber.Split('_')[0];
                }
                if (receivedData.Result_code.ToUpper() == "SUCCESS")  //支付成功
                {
                    OrderPaymentInfo info = null;
                    if (!string.IsNullOrEmpty(out_trade_no))
                    {
                        info = new OrderPaymentInfo
                        {
                            OrderNumber = out_trade_no,
                            TradeNumber = transaction_id,
                            TransferAmount = Convert.ToDecimal(total_fee) / 100,
                            InDate = DateTime.Now,
                            BuyerPaymentID = receivedData.OpenId,
                            PaymentPlatformType = 3,
                            InUser = 100
                        };
                    }
                    else
                    {
                        info = new OrderPaymentInfo
                        {
                            OrderNumber = orderNumberFlage,
                            TradeNumber = receivedData.Transaction_id,
                            TransferAmount = Convert.ToDecimal(receivedData.Total_fee) / 100,
                            InDate = DateTime.Now,
                            BuyerPaymentID = receivedData.OpenId,
                            PaymentPlatformType = 3,
                            InUser = 100,
                            OriginalOrderNumber = receivedData.OrderNumber
                        };
                    }
                    var response = ServiceHelper.CreateOrderPaymentInfo(info);
                    //2.发货通知，O2O支付成功就立即调用发货接口
                    //2.1.获取AccessToken
                    var utils = new Utils();
                    var access_token = RiderShop.Mobile.Common.ThirdEntity.Utility.GetAccess_Token();

                    //2.2.向微信发送发货通知
                    var strMsg = utils.SendDeliverNotify(access_token, receivedData.OpenId, receivedData.Transaction_id, receivedData.OrderNumber);

                    //return Redirect(ConfigurationManager.AppSettings["TenPayV3_PaymentCompleted"]);
                    return Content("success");
                }
                else
                {
                    return Content("fail");
                }
            }
            catch (Exception ex)
            {
                Kevin.Comm.Logger.Tracer.Error(ex);
                return Content("fail:" + ex.ToString());
            }
        }


        public ActionResult JsApiConfig(string orderNumber, decimal amount, string completedUrl, string notifyUrl, string title = "", string openId = "")
        {
            Kevin.Comm.Logger.Tracer.TraceLog(orderNumber, "JsApiConfigStart", "JsApiConfig", true);

            if (string.IsNullOrEmpty(openId))
            {
                //string orderNumber = Request["orderNumber"];
                string code = Request["code"];
                if (string.IsNullOrEmpty(code))
                {
                    var oathUrl = OAuth.GetAuthorizeUrl(TenPayV3Info.AppId, Request.Url.ToString(), orderNumber, OAuthScope.snsapi_base);
                    Response.Redirect(oathUrl);

                    Kevin.Comm.Logger.Tracer.TraceLog(Request.Url.ToString(), "JsApiConfigUrl", "JsApiConfig", true);
                    //Kevin.Comm.Logger.Tracer.TraceLog(oathUrl, "JsApiConfig", "JsApiConfig", true);
                    return View();
                }

                //Kevin.Comm.Logger.Tracer.TraceLog(Request.Url.ToString(), "JsApiConfigWithCode", "JsApiConfig", true);
                //通过，用code换取access_token
                var openIdResult = OAuth.GetAccessToken(TenPayV3Info.AppId, TenPayV3Info.AppSecret, code);
                if (openIdResult.errcode != ReturnCode.请求成功)
                {
                    return Content("错误：" + openIdResult.errmsg);
                }
                openId = openIdResult.openid;
            }
            string timeStamp = "";
            string nonceStr = "";
            string paySign = "";
            //orderNumber = state;

            try
            {

                //创建支付应答对象
                RequestHandler packageReqHandler = new RequestHandler(null);
                //初始化
                packageReqHandler.Init();
                //packageReqHandler.SetKey(""/*TenPayV3Info.Key*/);
                //var order = ServiceHelper.GetOrderDetailInfo(orderNumber);

                timeStamp = TenPayUtil.GetTimestamp();
                nonceStr = TenPayUtil.GetNoncestr();

                //TenPayV3Info.TenPayV3Notify = ConfigurationManager.AppSettings["TenPayV3_TenpayNotify"];
                TenPayV3Info.TenPayV3Notify = notifyUrl;

                //设置package订单参数
                packageReqHandler.SetParameter("appid", TenPayV3Info.AppId);		  //公众账号ID
                packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId);		  //商户号
                packageReqHandler.SetParameter("nonce_str", nonceStr);                    //随机字符串
                packageReqHandler.SetParameter("body", string.IsNullOrEmpty(title) ? "购买商品" : title);
                packageReqHandler.SetParameter("out_trade_no", orderNumber);		//商家订单号
                packageReqHandler.SetParameter("total_fee", (amount * 100M).ToString("0"));			        //商品金额,以分为单位(money * 100).ToString()
                packageReqHandler.SetParameter("spbill_create_ip", Request.UserHostAddress);   //用户的公网ip，不是商户服务器IP
                packageReqHandler.SetParameter("notify_url", TenPayV3Info.TenPayV3Notify);		    //接收财付通通知的URL
                packageReqHandler.SetParameter("trade_type", TenPayV3Type.JSAPI.ToString());	                    //交易类型
                packageReqHandler.SetParameter("openid", openId);	                    //用户的openId

                string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
                packageReqHandler.SetParameter("sign", sign);	                    //签名

                string data = packageReqHandler.ParseXML();
                Kevin.Comm.Logger.Tracer.TraceLog(data, "weixinPayData", "JsApiConfig", true);

                var result = TenPayV3.Unifiedorder(data);
                Kevin.Comm.Logger.Tracer.TraceLog(result, "weixinPayresult", "JsApiConfig", true);
                var res = XDocument.Parse(result);
                string prepayId = res.Element("xml").Element("prepay_id").Value;

                //设置支付参数
                RequestHandler paySignReqHandler = new RequestHandler(null);
                paySignReqHandler.SetParameter("appId", TenPayV3Info.AppId);
                paySignReqHandler.SetParameter("timeStamp", timeStamp);
                paySignReqHandler.SetParameter("nonceStr", nonceStr);
                paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
                paySignReqHandler.SetParameter("signType", "MD5");
                paySign = paySignReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);

                ViewData["appId"] = TenPayV3Info.AppId;
                ViewData["timeStamp"] = timeStamp;
                ViewData["nonceStr"] = nonceStr;
                ViewData["package"] = string.Format("prepay_id={0}", prepayId);
                ViewData["paySign"] = paySign;

                ViewBag.AppId = TenPayV3Info.AppId;
                ViewBag.CompletedUrl = completedUrl;
                ViewBag.timeStamp = timeStamp;
                ViewBag.NonceStr = nonceStr;
                ViewBag.Package = string.Format("prepay_id={0}", prepayId); ;
                ViewBag.SignType = "MD5";
                ViewBag.Sign = paySignReqHandler.CreateMd5Sign("key", TenPayV3Info.Key); ;

            }
            catch (Exception ex)
            {
                Kevin.Comm.Logger.Tracer.TraceLog(ex.Message, "weixinPayMessage", "JsApiConfig", true);
                Kevin.Comm.Logger.Tracer.Error(ex);

            }
            //Kevin.Comm.Logger.Tracer.TraceLog("End", "weixinPayView", "JsApiConfig", true);
            return View();
        }


        public ActionResult PayNotifyUrlSuccess()
        {
            try
            {
                //Url信息
                var sign = Request.Form["sign"];
                var trade_mode = Request.Form["trade_mode"];
                var trade_state = Request.Form["trade_state"];
                var partner = Request.Form["partner"];
                var bank_type = Request.Form["bank_type"];
                var total_fee = Request.Form["total_fee"];
                var fee_type = Request.Form["fee_type"];
                var notify_id = Request.Form["notify_id"];
                var transaction_id = Request.Form["transaction_id"];
                var out_trade_no = Request.Form["out_trade_no"];
                var time_end = Request.Form["time_end"];

                //PostData信息
                var receivedData = new ReceivedData(Request, 1);
                Kevin.Comm.Logger.Tracer.TraceLog(receivedData.RawXml, "weixinPayNotify", "JsApiConfig", true);

                if (receivedData.Result_code.ToUpper() == "SUCCESS")  //支付成功
                {
                    ////

                    /////

                    ////2.发货通知，O2O支付成功就立即调用发货接口
                    ////2.1.获取AccessToken
                    //var utils = new Utils();
                    //var access_token = RiderShop.Mobile.Common.ThirdEntity.Utility.GetAccess_Token();

                    ////2.2.向微信发送发货通知
                    //var strMsg = utils.SendDeliverNotify(access_token, receivedData.OpenId, receivedData.Transaction_id, receivedData.OrderNumber);

                    //Kevin.Comm.Logger.Tracer.TraceLog(strMsg, "weixinPaystrMsg", "JsApiConfig", true);
                    return Content("success");
                }
                else
                {
                    return Content("fail");
                }
            }
            catch (Exception ex)
            {
                Kevin.Comm.Logger.Tracer.Error(ex);
                return Content("fail:" + ex.ToString());
            }
        }
    }
}
